package vendas.business;

import gminet.infra.business.BusinessException;
import gminet.infra.business.BusinessObject;
import gminet.infra.db.Transaction;
import gminet.infra.db.TransactionException;
import gminet.infra.toolkit.NumberToolkit;
import gminet.infra.toolkit.StringToolkit;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import vendas.dao.OrderDAO;
import vendas.dao.OrderFilter;
import vendas.dao.SellerDAO;
import vendas.dto.ActiveStatus;
import vendas.dto.Order;
import vendas.dto.Seller;

public class SellerBusiness extends BusinessObject {

    private static List<Seller> cacheSellerList = null;

    public static Seller findByPK(int sellerId) throws BusinessException, TransactionException {

        Seller seller = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            seller = SellerDAO.findByPK(sellerId, conn);
            if (seller == null) {
                throw new BusinessException("Fornecedor não encontrado.");
            }
        } finally {
            transaction.release();
        }
        return seller;
    }

    public static List<Seller> findAll() throws TransactionException {
        
        return findAll(false);
    }

    public static List<Seller> findAll(boolean useCache) throws TransactionException {

        List<Seller> sellers = null;
        Transaction transaction = createTransaction();
        try {
            if (useCache) {
                if (cacheSellerList == null) {
                    Connection conn = transaction.getConnection();
                    cacheSellerList = SellerDAO.findAll(conn);
                }
                sellers = new ArrayList<Seller>(cacheSellerList);
            } else {
                Connection conn = transaction.getConnection();
                sellers = SellerDAO.findAll(conn);
            }

        } finally {
            transaction.release();
        }
        return sellers;
    }

    public static Seller insert(Seller seller) throws BusinessException, TransactionException {

        Seller newSeller = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            // SELLER
            int rangeId = createRangeId(seller.getName());
            seller.setId(SellerDAO.getNextCodigo(conn, rangeId, rangeId + 1000));
            seller.setActiveStatus(ActiveStatus.ACTIVE);
            if (!seller.getType().isWebUser()) {
                seller.setWebUserName(null);
            } else if (!StringToolkit.isFill(seller.getWebUserName())) {
                throw new BusinessException("Nome usuário web obrigatório para esse tipo.");
            }
            SellerDAO.insert(seller, conn);
            // COMMIT
            transaction.commit();
            //
            newSeller = seller;
            //
            clearCache();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return newSeller;
    }

    private static int createRangeId(String sellerName) {

        String strCodigo = "1";
        String caracter1 = sellerName.substring(0, 1).toUpperCase();
        String caracter2 = sellerName.substring(1, 2).toUpperCase();
        int valor1 = Math.abs(caracter1.compareTo("A") + 1);
        if (StringToolkit.isDigit(caracter1)) {
            valor1 = 0;
        }
        int valor2 = Math.abs(caracter2.compareTo("A") / 3);
        if (StringToolkit.isDigit(caracter2)) {
            valor2 = 0;
        }
        strCodigo += NumberToolkit.getStringFromInt(Math.min(valor1, 99), 2);
        strCodigo += NumberToolkit.getStringFromInt(Math.min(valor2, 9), 1);
        strCodigo += "000";
        return Integer.parseInt(strCodigo);
    }

    public static void update(Seller seller) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            Seller auxSeller = SellerDAO.findByPK(seller.getId(), conn);
            seller.setActiveStatus(auxSeller.getActiveStatus());
            if (!seller.getType().isWebUser()) {
                seller.setWebUserName(null);
            } else if (!StringToolkit.isFill(seller.getWebUserName())) {
                throw new BusinessException("Nome usuário web obrigatório para esse tipo.");
            }
            SellerDAO.update(seller, conn);
            // COMMIT
            transaction.commit();
            //
            clearCache();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void updateActiveStatus(Seller seller) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            boolean deleted = false;
            //
            if (seller.getActiveStatus().equals(ActiveStatus.INACTIVE)) {
                OrderFilter orderFilter = new OrderFilter();
                orderFilter.setSeller(seller);
                List<Order> orders = OrderDAO.findByFilter(orderFilter, conn);
                if (orders.size() == 0) {
                    SellerDAO.delete(seller, conn);
                    deleted = true;
                }
            }
            //
            if (!deleted) {
                Seller auxSeller = SellerDAO.findByPK(seller.getId(), conn);
                seller.setName(auxSeller.getName());
                seller.setComents(auxSeller.getComents());
                SellerDAO.update(seller, conn);
            }
            // COMMIT
            transaction.commit();
            //
            clearCache();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void delete(Seller seller) throws TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            SellerDAO.delete(seller, conn);
            transaction.commit();
            //
            clearCache();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    private static void clearCache() {

        if (cacheSellerList != null) {
            cacheSellerList.clear();
        }
        cacheSellerList = null;
    }

}
